// This file goes through the HTML on the page and adds various context options such as
// the ability to collapse lists.

// Options menu variable local storage.
var collapsing = true;
var collapse_style = 1;
var show_crossed = true;
var show_lightgray = true;
var show_gray = true;
var show_levels = [0,2,3,4];

// Add Hotkeys
$.hotkeys.add('alt+o', function(){
  toggleLists("open");
});
$.hotkeys.add('alt+i', function(){
  toggleLists("collapse");
});    

// Observe settings menu controls.
document.addEventListener('DOMContentLoaded', function() {
  $("#collapse_on").click(function() {
    chrome.storage.local.get('collapsing', function (result) {
      if (result.collapsing == false) {
        chrome.storage.local.set({'collapsing': true});
        collapsing = true;
      
        // Send a request to add collapsibles.
        chrome.tabs.getSelected(null, function(tab) {
          chrome.tabs.sendRequest(tab.id, {action: "addCollapsibles"}, function(response) {});
        });
      }
    });
  });
  $("#collapse_off").click(function() {
    chrome.storage.local.get('collapsing', function (result) {
      if (result.collapsing == true) {
        chrome.storage.local.set({'collapsing': false});
        collapsing = false;
      
        // Send a request to remove collapsibles.
        chrome.tabs.getSelected(null, function(tab) {
          chrome.tabs.sendRequest(tab.id, {action: "removeCollapsibles"}, function(response) {});
        });
      }
    });
  });
  $("#collapse_all").click(function() {
    // Send a request to collapse all.
    chrome.tabs.getSelected(null, function(tab) {
      chrome.tabs.sendRequest(tab.id, {action: "collapseAll"}, function(response) {});
    });
  });
  $("#open_all").click(function() {
    // Send a request to open all.
    chrome.tabs.getSelected(null, function(tab) {
      chrome.tabs.sendRequest(tab.id, {action: "openAll"}, function(response) {});
    });
  });
  $("#collapse_style1").click(function() {
    chrome.storage.local.get('collapse_style', function (result) {
      if (result.collapse_style != 1) {
        chrome.storage.local.set({'collapse_style': 1});

        // Send a request to change collapse style to 1.
        chrome.tabs.getSelected(null, function(tab) {
          chrome.tabs.sendRequest(tab.id, {action: "collapse_style_1"}, function(response) {});
        });
      }
    });
  });
  $("#collapse_style2").click(function() {
    chrome.storage.local.get('collapse_style', function (result) {
      if (result.collapse_style != 2) {
        chrome.storage.local.set({'collapse_style': 2});
        collapse_style = 2;
      
        // Send a request to change collapse style to 2.
        chrome.tabs.getSelected(null, function(tab) {
          chrome.tabs.sendRequest(tab.id, {action: "collapse_style_2"}, function(response) {});
        });
      }
    });
  });
  $("#show_crossed").change(function() {
    var checked = ($(this).attr("checked") == "checked") ? true : false;
    chrome.storage.local.set({'show_crossed': checked});
    // Send a request to toggle crossed out content.
    chrome.tabs.getSelected(null, function(tab) {
      chrome.tabs.sendRequest(tab.id, {action: "toggle_crossed"}, function(response) {});
    });
  });
  $("#show_lightgray").change(function() {
    var checked = ($(this).attr("checked") == "checked") ? true : false;
    chrome.storage.local.set({'show_lightgray': checked});
    // Send a request to toggle lightgray content.
    chrome.tabs.getSelected(null, function(tab) {
      chrome.tabs.sendRequest(tab.id, {action: "toggle_lightgray"}, function(response) {});
    });
  });
  $("#show_gray").change(function() {
    var checked = ($(this).attr("checked") == "checked") ? true : false;
    chrome.storage.local.set({'show_gray': checked});
    // Send a request to toggle lightgray content.
    chrome.tabs.getSelected(null, function(tab) {
      chrome.tabs.sendRequest(tab.id, {action: "toggle_gray"}, function(response) {});
    });
  });
  $("#show_level1, #show_level2, #show_level3, #show_level4plus").change(function() {
    var checkedLevels = [0, 0, 0, 0];
    
    if ($("#show_level1").prop("checked")) {
      checkedLevels[0] = 1;
    }
    if ($("#show_level2").prop("checked")) {
      checkedLevels[1] = 2;
    }
    if ($("#show_level3").prop("checked")) {
      checkedLevels[2] = 3;
    }
    if ($("#show_level4plus").prop("checked")) {
      checkedLevels[3] = 4;
    }

    chrome.storage.local.set({'show_levels': JSON.stringify(checkedLevels)});
    
    // Send a request to show correct levels content.
    chrome.tabs.getSelected(null, function(tab) {
      chrome.tabs.sendRequest(tab.id, {action: "show_levels"}, function(response) {});
    });
  });
});

// Listen for requests from popup.html
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
  // Remove collapsibles request.
  if (request.action == "removeCollapsibles") {
    removeCollapsibles();
  } else if (request.action == "addCollapsibles") {
    injectPage();
  // Change collapse icons.
  } else if (request.action == "collapse_style_1" || request.action == "collapse_style_2") {
    var styleNum = (request.action == "collapse_style_1") ? 1 : 2;
    var collapsers = $(".collapser");
    
    collapse_style = styleNum;
    
    for (var i = 0; i < collapsers.length; i++) {
      if ($(collapsers[i]).hasClass("open_collapser")) {
        $(collapsers[i]).attr("src", chrome.extension.getURL("images/collapse" + styleNum + ".png"));
      } else {
        $(collapsers[i]).attr("src", chrome.extension.getURL("images/open" + styleNum + ".png"));
      }
    }
  // Toggle the appropriate list levels if collapsing is enabled.
  } else if (request.action == "show_levels") {
    chrome.storage.local.get('show_levels', function (result) {
      show_levels = JSON.parse(result.show_levels);
      
      $("#toolbar_level1").attr("checked", (show_levels[0] == 1));
      $("#toolbar_level2").attr("checked", (show_levels[1] == 2));
      $("#toolbar_level3").attr("checked", (show_levels[2] == 3));
      $("#toolbar_level4plus").attr("checked", (show_levels[3] == 4));

      if (collapsing) {  
        removeCollapsibles();
        injectPage();
      } 
    });
  // Toggle crossed-out content.
  } else if (request.action == "toggle_crossed") {
    toggleCrossed();
    $("#toolbar_crossed").attr("checked", !($("#toolbar_crossed").attr("checked")));
  // Toggle lightgray content.   
  } else if (request.action == "toggle_lightgray") {
    $("#toolbar_lightgray").attr("checked", !($("#toolbar_lightgray").attr("checked")));
    toggleFont("lightgray");
  // Toggle gray content.     
  } else if (request.action == "toggle_gray") {
    $("#toolbar_gray").attr("checked", !($("#toolbar_gray").attr("checked")));
    toggleFont("gray");
  // Collapse All
  } else if (request.action == "collapseAll") {
    toggleLists("collapse");
  // Open All
  } else if (request.action == "openAll") {
    toggleLists("open");
  }
});

//
// MAIN ENTRY POINT:
//

// SET UP OPTIONS CHECKBOXES
chrome.storage.local.get('show_crossed', function (result) {
  if (result.show_crossed != null) {
    show_crossed = result.show_crossed;
    $("#show_crossed").attr("checked", show_crossed);
  } else {
    chrome.storage.local.set({'show_crossed': true});
    show_crossed = true;
    $("#show_crossed").attr("checked", true);
  }
});
chrome.storage.local.get('show_lightgray', function (result) {
  if (result.show_lightgray != null) {
    show_lightgray = result.show_lightgray;
    $("#show_lightgray").attr("checked", show_lightgray);
  } else {
    chrome.storage.local.set({'show_lightgray': true});
    show_lightgray = true;
    $("#show_lightgray").attr("checked", true);
  }
});
chrome.storage.local.get('show_gray', function (result) {
  if (result.show_gray != null) {
    show_gray = result.show_gray;
    $("#show_gray").attr("checked", show_gray);
  } else {
    chrome.storage.local.set({'show_gray': true});
    show_gray = true;
    $("#show_gray").attr("checked", true);
  }
});
chrome.storage.local.get('show_levels', function (result) {
  if (result.show_levels != null) {
    var levels = JSON.parse(result.show_levels);
    window.show_levels = levels;
    $("#show_level1").attr("checked", (levels[0] == 1));
    $("#show_level2").attr("checked", (levels[1] == 2));
    $("#show_level3").attr("checked", (levels[2] == 3));
    $("#show_level4plus").attr("checked", (levels[3] == 4));
  } else {
    chrome.storage.local.set({'show_levels': JSON.stringify([0,2,3,4])});
    window.show_levels = [0,2,3,4];
    $("#show_level1").attr("checked", false);
    $("#show_level2").attr("checked", true);
    $("#show_level3").attr("checked", true);
    $("#show_level4plus").attr("checked", true);
  }
});

// Only run parsing/enchancements on *wiki* pages.
if (window.location.href.indexOf("wiki") > -1) {
  chrome.storage.local.get('collapse_style', function (result) {
    if (result.collapse_style != null) {
      collapse_style = result.collapse_style;
    } else {
      chrome.storage.local.set({'collapse_style': 1});
    }
    
    chrome.storage.local.get('show_crossed', function (result) {
      if (result.show_crossed != null) {
        // Toggle crossed/greyed content out.
        if (!result.show_crossed) {
          toggleCrossed();
        } else {
          show_crossed = true;
        }
      } else {
        chrome.storage.local.set({'show_crossed': true});
        show_crossed = true;
      }
      
      chrome.storage.local.get('show_lightgray', function (result) {
        if (result.show_lightgray != null) {
          // Toggle crossed/greyed content out.
          if (!result.show_lightgray) {
            toggleFont("lightgray");
          } else {
            show_lightgray = true;
          }
        } else {
          chrome.storage.local.set({'show_lightgray': true});
          show_lightgray = true;
        }
        
        chrome.storage.local.get('show_gray', function (result) {
          if (result.show_gray != null) {
            // Toggle crossed/greyed content out.
            if (!result.show_gray) {
              toggleFont("gray");
            } else {
              show_gray = true;
            }
          } else {
            chrome.storage.local.set({'show_gray': true});
            show_gray = true;
          }
 
          chrome.storage.local.get('collapsing', function (result) {
            if (result.collapsing != null) {
              collapsing = result.collapsing;
              if (collapsing) {
                injectPage();
              }
            } else {
              chrome.storage.local.set({'collapsing': true});
              injectPage();
            }
          });
        });
      });
    });
  });
}

// Add additional context options for lists and inject the toolbar.
function injectPage () {
  makeListsCollapsible ($("ul"));
  makeListsCollapsible ($("ol"));
  
  // Create and display bottom-left toolbar (if it doesn't exist).
  if (!$("#wikiToolbar").length) {
    var toolbar = document.createElement("div");
    $(toolbar).attr("id", "wikiToolbar");
    $(toolbar).css("width", "153px");
    $(toolbar).css("height", "230px");
    $(toolbar).css("position", "fixed");
    $(toolbar).css("left", "0");
    $(toolbar).css("bottom", "0");
    $(toolbar).css("padding-left", "5px");
    $(toolbar).css("text-align", "center");

    var title = document.createElement("h3");
    $(title).html("W<sup>2</sup>");
    $(title).css("font-family", "Garamond, Georgia, serif");
    var listTitle = document.createElement("p");
    $(listTitle).text("Collapsible List Levels");
    $(listTitle).css("font-size", "11pt");
    var contentTitle = document.createElement("p");
    $(contentTitle).text("Marked-Out Content");
    $(contentTitle).css("font-size", "11pt");
    
    var level1 = document.createElement("input");
    $(level1).attr("type", "checkbox");
    $(level1).css("cursor", "pointer");
    $(level1).attr("id", "toolbar_level1");
    var level2 = document.createElement("input");
    $(level2).attr("type", "checkbox");
    $(level2).css("cursor", "pointer");
    $(level2).attr("id", "toolbar_level2");
    var level3 = document.createElement("input");
    $(level3).attr("type", "checkbox");
    $(level3).css("cursor", "pointer");
    $(level3).attr("id", "toolbar_level3");
    var level4 = document.createElement("input");
    $(level4).attr("type", "checkbox");
    $(level4).css("cursor", "pointer");
    $(level4).attr("id", "toolbar_level4");
    $(level4).css("margin-bottom", "10px");
    
    var leftAlign = document.createElement("div");
    $(leftAlign).css("text-align", "left");
    $(leftAlign).css("padding-left", "20px");
    var crossed = document.createElement("input");
    $(crossed).attr("type", "checkbox");
    $(crossed).css("cursor", "pointer");
    $(crossed).attr("id", "toolbar_crossed");
    var lightgray = document.createElement("input");
    $(lightgray).attr("type", "checkbox");
    $(lightgray).css("cursor", "pointer");
    $(lightgray).attr("id", "toolbar_lightgray");
    var gray = document.createElement("input");
    $(gray).attr("type", "checkbox");
    $(gray).css("cursor", "pointer");
    $(gray).attr("id", "toolbar_gray");
    
    if (show_levels[0] == 1) {
      $(level1).attr("checked", true);
    }
    if (show_levels[1] == 2) {
      $(level2).attr("checked", true);
    }
    if (show_levels[2] == 3) {
      $(level3).attr("checked", true);
    }
    if (show_levels[3] == 4) {
      $(level4).attr("checked", true);
    }
    if (show_crossed) {
      $(crossed).attr("checked", true);
    }
    if (show_lightgray) {
      $(lightgray).attr("checked", true);
    }
    if (show_gray) {
      $(gray).attr("checked", true);
    }
    
    $(toolbar).append(title);
    $(toolbar).append(listTitle);
    
    $(toolbar).append(level1);
    $(toolbar).append("1");
    $(toolbar).append(level2);
    $(toolbar).append("2");
    $(toolbar).append(level3);
    $(toolbar).append("3");
    $(toolbar).append(level4);
    $(toolbar).append("4+");
    
    $(toolbar).append("<hr>");
    $(toolbar).append(contentTitle);
    
    // Don't show grey/lightgrey and strikethrough options if none exist on the page.
    
    
    if ($("s").length > 0) {
      $(leftAlign).append(crossed);
      $(leftAlign).append("<label for='toolbar_crossed'>Crossed</label>");
      $(leftAlign).append("<br>");
    }

    if ($("font[color='lightgray']").length > 0) {
      $(leftAlign).append(lightgray);
      $(leftAlign).append("<label for='toolbar_lightgray'>Light Gray</label>");
      $(leftAlign).append("<br>");
    }
    if ($("font[color='gray']").length > 0) {
      $(leftAlign).append(gray);
      $(leftAlign).append("<label for='toolbar_gray'>Gray</label>");
    }
    
    $(toolbar).append(leftAlign);
    $("body").append(toolbar);
    
    // Bind actions to all toolbar controls.
    var levels = [level1, level2, level3, level4];
    $.each(levels, function() {
      $(this).change(function() {
        var checkedLevels = [0, 0, 0, 0];
      
        if ($(level1).prop("checked")) {
          checkedLevels[0] = 1;
        }
        if ($(level2).prop("checked")) {
          checkedLevels[1] = 2;
        }
        if ($(level3).prop("checked")) {
          checkedLevels[2] = 3;
        }
        if ($(level4).prop("checked")) {
          checkedLevels[3] = 4;
        }
        chrome.storage.local.set({'show_levels': JSON.stringify(checkedLevels)});
        chrome.storage.local.get('show_levels', function (result) {
          show_levels = JSON.parse(result.show_levels);
          if (collapsing) {  
            removeCollapsibles();
            injectPage();
          } 
        });
      });
    });
    
    $(crossed).change(function() {
      var checked = ($(this).attr("checked") == "checked") ? true : false;
      chrome.storage.local.set({'show_crossed': checked});
      toggleCrossed();
    });
    
    $(lightgray).change(function() {
      var checked = ($(this).attr("checked") == "checked") ? true : false;
      chrome.storage.local.set({'show_lightgray': checked});
      toggleFont("lightgray");
    });
    
    $(gray).change(function() {
      var checked = ($(this).attr("checked") == "checked") ? true : false;
      chrome.storage.local.set({'show_gray': checked});
      toggleFont("gray");
    });
  }
}

// Takes a collection of lists and makes them collapsible.
function makeListsCollapsible (lists) {
 for (var i = 0; i < lists.length; i++) {
    // Flags an invalid list.
    var invalidList = false;
    
    // Store the parent elements of each list.
    var listParents = $(lists[i]).parents();
    // Is one of the parents a list?
    var parentListCount = 0;
    
    // Exclude table of contents, header, menu, footer, etc. lists.
    for (var x = 0; x < listParents.length; x++) {
      var parentId = $(listParents[x]).attr("id");
      
      if ($(listParents[x]).is("ul") || $(listParents[x]).is("ol")) {
        parentListCount++;
      }
      
      if (parentId == "toc" || parentId == "footer" || parentId == "header" || parentId == "menu" || parentId == "mw-panel" || parentId == "mw-head" || parentId == "catlinks" || parentId == "wikiToolbar" || $(listParents[x]).hasClass("infobox")) {
        invalidList = true;
        break;
      }
    }
    
    // Store left align value based on "level"
    var left = 0;
    // Allow only the corrent numbers of list "parents" lists - based on user settings.

    switch (parentListCount) {
      case 0:
        left = -22;
        if (window.show_levels[0] != 1) {
          invalidList = true;
        }
        break;
      case 1:
        if(($(lists[i])).get(0).tagName == "UL") {
          left = 5;
        } else {
          left = 22
        }
        
        if (window.show_levels[1] != 2) {
          invalidList = true;
        }
        break;
      case 2:
        if(($(lists[i])).get(0).tagName == "UL") {
          left = 28;
        } else {
          left = 67;
        }
        
        if (window.show_levels[2] != 3) {
          invalidList = true;
        }
        break;
      default:
        if(($(lists[i])).get(0).tagName == "UL") {
          left = 28 + ((parentListCount - 2) * 23);
        } else {
          left = 67 + ((parentListCount - 1) * 23);
        }
        
        if (window.show_levels[3] != 4) {
          invalidList = true;
        }
        break;
    }
    
    // BUGBUG
    if(($(lists[i])).get(0).tagName == "UL") {
      left = lists[i].getBoundingClientRect().left - 240;
    } else {
      left = lists[i].getBoundingClientRect().left - 269;
    }
    
    // Do not process an invalid list.
    if (invalidList) {
      continue;
    }
    
    // Add a clickable collapse/open icon to lists.
    var div = document.createElement("div");
    var collapser = document.createElement("img");
    $(collapser).addClass("collapser");
    $(collapser).addClass("open_collapser");
    $(collapser).css("cursor", "pointer");
    $(collapser).css("display", "none");
    $(collapser).css("position", "absolute");

    // Left position depends on which level list it is.
    $(collapser).css("left", left + "px");
    //$(collapser).css("margin-top", "-22px");
    $(collapser).css("margin-top", "-8px");
    
    // Level 1 List Gets extra room.
    if (parentListCount == 0) {
      $(div).css("height", "10px");
    }

    // Get collapse style
    $(collapser).attr("src", chrome.extension.getURL("images/collapse" + collapse_style + ".png"));

    $(div).append(collapser);
    $(lists[i]).prepend(div);
    $(collapser).slideDown("fast");

    $(collapser).click(function() {
      var siblings = $(this).parent().parent().children();
      for (var y = 0; y < siblings.length; y++) {
        // Don't hide/unhide the first "child" - this is the actual button.
        if (y > 0) {
          // Work around unsupported "font" and "s" tag issue.
          if ($(siblings[y]).is("font") || $(siblings[y]).is("s")) {
            $(siblings[y]).children().slideToggle("fast");
          } else {
            $(siblings[y]).slideToggle("fast");
          }
        }
      }
      
      var hr = document.createElement("hr");

      // Toggle image.
      if ($(this).hasClass("open_collapser")) {
        $(this).attr("src", chrome.extension.getURL("images/open" + collapse_style + ".png"));
        $(this).removeClass("open_collapser");
        $(this).parent().append(hr);
      } else {
        $(this).attr("src", chrome.extension.getURL("images/collapse" + collapse_style + ".png"));
        $(this).addClass("open_collapser");
        $(this).parent().find("hr").remove();
      }
    });
  }
}

// Turns off collapsible features (resetting toggled lists and removing images).
function removeCollapsibles () {
  var collapsers = $(".collapser");
  
  for (var i = 0; i < collapsers.length; i++) {
    $(collapsers[i]).slideUp("fast", function() {
      var siblings = $(collapsers[i]).parent().parent().children();
      for (var y = 0; y < siblings.length; y++) {
        // Work around unsupported "font" tag issue.
        if ($(siblings[y]).is("font")) {
          $(siblings[y]).children().slideDown("fast");
        } else {
          $(siblings[y]).slideDown("fast");
        }
      }
      
      $(collapsers[i]).parent().css("height", "0px");
      $(collapsers[i]).parent().remove();
      $(collapsers[i]).remove();
    });
  }
}

// Toggles crossed out content on the screen.
function toggleCrossed() {
  var strikethrough = $("s");
  for (var i = 0; i < strikethrough.length; i++) {
    if ($(strikethrough[i]).parent().is("li")) {
      $(strikethrough[i]).parent().slideToggle("fast");
    }
    $(strikethrough[i]).slideToggle("fast");
  }
}

// Toggles a type of <font> tag based on color.
function toggleFont (color) {
  var fonts = $("font[color='" + color + "']");
  for (var i = 0; i < fonts.length; i++) {
    if ($(fonts[i]).parent().is("li")) {
      $(fonts[i]).parent().slideToggle("fast");
    }
    $(fonts[i]).slideToggle("fast");
    $(fonts[i]).children().slideToggle("fast");
  }
}

// Either collapses or opens all of the lists currently visible.
function toggleLists (action) {
  var collapsibles = $(".collapser");
  
  if (action == "collapse") {
    $(collapsibles).each(function () {
      if ($(this).hasClass("open_collapser")) {
        $(this).trigger("click");
      }
    });
  } else if (action == "open") {
    $(collapsibles).each(function () {
      if (!$(this).hasClass("open_collapser")) {
        $(this).trigger("click");
      }
    });
  }
}
